package com.baofu.paycore.service.validate;

import com.baofu.paycore.common.enums.RedisKeyEnum;
import com.baofu.paycore.manager.model.PayBaseBO;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.baofu.paycore.manager.cache.RedisLockManager;
import com.baofu.paycore.manager.storer.OrderRepository;
import com.baofu.paycore.service.facade.enums.PayStatusEnums;
import com.baofu.paycore.common.exception.ServiceErrorCode;
import com.baofu.paycore.service.facade.model.PayBaseDTO;
import com.baofu.paycore.common.exception.ValidateException;
import com.google.common.base.Objects;
import com.system.commons.result.Result;
import com.system.commons.utils.BeanCopyUtil;
import com.system.commons.utils.ParamValidate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * User: LZQ
 *
 * 服务参数校验基础类
 */
@Slf4j
@Service
public abstract class AbstractPayValidate<T extends PayBaseDTO> {

    /**
     * 订单锁服务
     */
    @Autowired
    private RedisLockManager lockManager;

    /**
     * 参数基本校验 格式及非空校验
     * @param t     被校验对象
     */
    public void paramsValidate(T t){
        ParamValidate.validateParams(t);
    }

    /**
     * 金额校验
     * @param amt       反向交易主订单金额
     * @param oldAmt    原交易主单金额
     */
    protected void amtValidate(long amt,long oldAmt){
        if(amt != oldAmt){
            log.error("金额校验异常 主单金额：{}，原交易主单金额：{}",amt,oldAmt);
            throw new ValidateException(PayCoreErrorCode.AMT_IS_NOT_IN_CONFORMITY);
        }
    }


    protected void validateOrderStatus(String status){
        if(!Objects.equal(PayStatusEnums.SUCCESS.getCode(),status)){
            log.error("原订单状态交易未成功 {}",status);
            throw new ValidateException(ServiceErrorCode.ORDER_STATUS_NOT_SUCCESS);
        }
    }

    /**
     * 锁定支付订单
     *
     * @param t     被校验对象
     */
    public boolean lock(T t){
        return lockManager.lock(RedisKeyEnum.PAY_SERVICE,t.getRequestBizNo(),t.getRequestOrderNo());
    }

    /**
     * 释放订单锁
     *
     * @param t     被校验对象
     */
    public void release(T t,boolean flag){
        if(flag){
            lockManager.release(RedisKeyEnum.PAY_SERVICE,t.getRequestBizNo(),t.getRequestOrderNo());
        }
    }

    /**
     * 订单唯一性校验
     *
     * @param t     被校验对象
     */
    public <E> Result<E> validateUniqueOrder(T t,OrderRepository orderRepository,Class<E> clazz){
        PayBaseBO order = orderRepository.checkIdempotent(t.getRequestBizNo(),t.getRequestOrderNo(),t.getRequestSystem());
        if (order != null) {
            log.warn("订单已存在:{},{}",t.getRequestBizNo(),t.getRequestOrderNo());
            return new Result<>(BeanCopyUtil.objConvert(order,clazz));
        }
        return null;
    }
}
